home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 676-700 / 681 / term / source.lha / termPhone.c < prev    next >
C/C++ Source or Header  |  1992-05-09  |  32KB  |  1,401 lines

  1. /*
  2. **    $Id: termPhone.c,v 1.5 92/05/05 18:12:07 olsen Sta Locker: olsen $
  3. **    $Revision: 1.5 $
  4. **    $Date: 92/05/05 18:12:07 $
  5. **
  6. **    Phonebook support routines
  7. **
  8. **    Copyright © 1990-1992 by Olaf `Olsen' Barthel & MXM
  9. **        All Rights Reserved
  10. */
  11.  
  12. #include "termGlobal.h"
  13.  
  14. #define RAWSIZE (sizeof(struct PhoneEntry) - offsetof(struct PhoneEntry,Name))
  15.  
  16.     /* Are we using the new includes? */
  17.  
  18. #ifdef ASLSM_FilterFunc
  19.  
  20.     /* Undefine the following symbols, the preferences header file
  21.      * will use the same names and the same values.
  22.      */
  23.  
  24. #undef PARITY_NONE
  25. #undef PARITY_EVEN
  26. #undef PARITY_ODD
  27. #undef PARITY_MARK
  28. #undef PARITY_SPACE
  29.  
  30.     /* Include the preferences header files. */
  31.  
  32. #include <prefs/prefhdr.h>
  33. #include <prefs/serial.h>
  34.  
  35.     /* Serial preferences data. */
  36.  
  37. STATIC BYTE            SerialPrefsRead        = FALSE,
  38.                 SerialPrefsReadFailed    = FALSE;
  39. STATIC struct SerialPrefs    SerialPrefs;
  40.  
  41.     /* ReadSerialPrefs():
  42.      *
  43.      *    Reads the default serial preferences settings.
  44.      */
  45.  
  46. STATIC BYTE
  47. ReadSerialPrefs()
  48. {
  49.     struct IFFHandle *Handle;
  50.  
  51.         /* Allocate an IFF handle. */
  52.  
  53.     if(Handle = AllocIFF())
  54.     {
  55.             /* Open the preferences settings file. */
  56.  
  57.         if(Handle -> iff_Stream = Open("ENV:sys/serial.prefs",MODE_OLDFILE))
  58.         {
  59.                 /* Make it known as a DOS file handle. */
  60.  
  61.             InitIFFasDOS(Handle);
  62.  
  63.                 /* Open the file for reading. */
  64.  
  65.             if(!OpenIFF(Handle,IFFF_READ))
  66.             {
  67.                     /* Stop at the `body' chunk. */
  68.  
  69.                 if(!StopChunk(Handle,ID_PREF,ID_SERL))
  70.                 {
  71.                         /* Look for it... */
  72.  
  73.                     if(!ParseIFF(Handle,IFFPARSE_SCAN))
  74.                     {
  75.                             /* Read the data. */
  76.  
  77.                         if(ReadChunkBytes(Handle,&SerialPrefs,sizeof(struct SerialPrefs)) == sizeof(struct SerialPrefs))
  78.                             SerialPrefsRead = TRUE;
  79.                     }
  80.                 }
  81.  
  82.                     /* Close the handle. */
  83.  
  84.                 CloseIFF(Handle);
  85.             }
  86.  
  87.                 /* Release the handle. */
  88.  
  89.             Close(Handle -> iff_Stream);
  90.         }
  91.  
  92.             /* Clean up. */
  93.  
  94.         FreeIFF(Handle);
  95.     }
  96.  
  97.         /* Return sucess/failure. */
  98.  
  99.     return(SerialPrefsRead);
  100. }
  101.  
  102. #endif    /* ASLSM_FilterFunc */
  103.  
  104.     /* SetPrefToDefaults():
  105.      *
  106.      *    Initialize configuration with default values.
  107.      */
  108.  
  109. VOID
  110. SetPrefToDefaults(struct Configuration *Config,UBYTE *PathBuffer)
  111. {
  112.     if(!PathBuffer)
  113.         PathBuffer = "TERM:config";
  114.  
  115.     strcpy(Config -> DefaultStorage,PathBuffer);
  116.  
  117. #ifdef ASLSM_FilterFunc
  118.  
  119.         /* The program will only try to read the preferences
  120.          * settings once; if the first access failed, no
  121.          * other accesses will be made.
  122.          */
  123.  
  124.     if(!SerialPrefsRead && !SerialPrefsReadFailed)
  125.         SerialPrefsReadFailed = ReadSerialPrefs() ^ TRUE;
  126.  
  127.         /* Did we succeed in reading the file? */
  128.  
  129.     if(!SerialPrefsRead)
  130.     {
  131.         Config -> BaudRate        = 2400;
  132.         Config -> BitsPerChar        = 8;
  133.         Config -> Parity        = PARITY_NONE;
  134.         Config -> StopBits        = 1;
  135.         Config -> Handshaking        = HANDSHAKING_XONXOFF;
  136.         Config -> SerBuffSize        = 32768;
  137.     }
  138.     else
  139.     {
  140.             /* Fill in the common data. */
  141.  
  142.         Config -> BaudRate        = SerialPrefs . sp_BaudRate;
  143.         Config -> SerBuffSize        = SerialPrefs . sp_InputBuffer;
  144.         Config -> BitsPerChar        = SerialPrefs . sp_BitsPerChar;
  145.         Config -> StopBits        = SerialPrefs . sp_StopBits;
  146.  
  147.             /* Convert the handshaking mode. */
  148.  
  149.         switch(SerialPrefs . sp_InputHandshake)
  150.         {
  151.             case HSHAKE_NONE:    Config -> Handshaking = HANDSHAKING_NONE;
  152.                         break;
  153.  
  154.             case HSHAKE_RTS:    Config -> Handshaking = HANDSHAKING_RTSCTS;
  155.                         break;
  156.  
  157.             default:        Config -> Handshaking = HANDSHAKING_XONXOFF;
  158.                         break;
  159.         }
  160.  
  161.             /* Convert the parity settings. */
  162.  
  163.         if(SerialPrefs . sp_Parity <= PARITY_SPACE)
  164.             Config -> Parity = SerialPrefs . sp_Parity;
  165.         else
  166.             Config -> Parity = PARITY_NONE;
  167.     }
  168.  
  169. #else
  170.  
  171.     Config -> BaudRate        = 2400;
  172.     Config -> BitsPerChar        = 8;
  173.     Config -> Parity        = PARITY_NONE;
  174.     Config -> StopBits        = 1;
  175.     Config -> Handshaking        = HANDSHAKING_XONXOFF;
  176.     Config -> SerBuffSize        = 32768;
  177.  
  178. #endif    /* ASLSM_FilterFunc */
  179.  
  180.     strcpy(Config -> SerialDevice,SERIALNAME);
  181.  
  182.     Config -> Duplex        = DUPLEX_FULL;
  183.     Config -> HighSpeed        = FALSE;
  184.     Config -> BreakLength        = 250000;
  185.     Config -> UnitNumber        = 0;
  186.  
  187.     /* Modem Preferences. */
  188.  
  189.     Config -> RedialDelay        = 2;
  190.     Config -> DialRetries        = 10;
  191.     Config -> DialTimeout        = 60;
  192.     Config -> ConnectAutoBaud    = FALSE;
  193.  
  194.     strcpy(Config -> ModemInit,    "ATZ\\r");
  195.     strcpy(Config -> ModemExit,    "");
  196.     strcpy(Config -> ModemHangup,    "~~~~~~~~+++\\r~~~~~~ATH0\\r");
  197.     strcpy(Config -> DialPrefix,    "~~ATDP");
  198.     strcpy(Config -> NoCarrier,    "NO CARRIER");
  199.     strcpy(Config -> Connect,    "CONNECT");
  200.     strcpy(Config -> Voice,        "VOICE");
  201.     strcpy(Config -> Ring,        "RING");
  202.     strcpy(Config -> Busy,        "BUSY");
  203.  
  204.     /* Transfer Preferences. */
  205.  
  206.     strcpy(Config -> Protocol,"xprzmodem.library");
  207.  
  208.     /* Macro Preferences. */
  209.  
  210.     if(!LastMacros[0])
  211.     {
  212.         strcpy(LastMacros,PathBuffer);
  213.  
  214.         AddPart(LastMacros,"macros.prefs",256);
  215.     }
  216.  
  217.     strcpy(Config -> MacroFile,LastMacros);
  218.  
  219.     /* Screen Preferences. */
  220.  
  221.     Config -> DisplayMode        = ModeID[0];
  222.     Config -> MakeScreenPublic    = TRUE;
  223.  
  224.     /* Terminal Preferences. */
  225.  
  226.     Config -> CaptureFilter        = TRUE;
  227.     Config -> DestructiveBackspace    = FALSE;
  228.     Config -> AudibleBell        = TRUE;
  229.     Config -> VisibleBell        = FALSE;
  230.     Config -> EightyColumns        = FALSE;
  231.     Config -> SendCR        = CR_ASCR;
  232.     Config -> SendLF        = LF_ASLF;
  233.     Config -> ColourMode        = COLOUR_AMIGA;
  234.     Config -> Emulation        = EMULATION_ANSIVT100;
  235.     Config -> Font            = FONT_TOPAZ;
  236.  
  237.     Config -> SwapBSDelete        = FALSE;
  238.     Config -> StripBit8        = FALSE;
  239.  
  240.     Config -> RasterEnabled        = TRUE;
  241.  
  242.     Config -> EmulationName[0]    = 0;
  243.  
  244.     Config -> StartupMacro[0]    = 0;
  245.     Config -> UploadMacro[0]    = 0;
  246.     Config -> DownloadMacro[0]    = 0;
  247.  
  248.     if(!LastFastMacros[0])
  249.     {
  250.         strcpy(LastFastMacros,PathBuffer);
  251.  
  252.         AddPart(LastFastMacros,"fastmacros.prefs",256);
  253.     }
  254.  
  255.     strcpy(Config -> FastMacroFile,LastFastMacros);
  256.  
  257.     Config -> Priority        = 0;
  258.     Config -> OverridePath        = TRUE;
  259.     Config -> BackupConfig        = FALSE;
  260.     Config -> AutoUpload        = TRUE;
  261.  
  262.     strcpy(Config -> NoDialTone,"NO DIALTONE");
  263.  
  264.     Config -> TitleBar        = TRUE;
  265.     Config -> StatusLine        = TRUE;
  266.  
  267.     Config -> DropDTR        = FALSE;
  268.  
  269.     Config -> MaxLogBuffSize    = 0;
  270.     Config -> BufferEnabled        = TRUE;
  271.  
  272.     Config -> ReceiveCR        = CR_ASCR;
  273.     Config -> ReceiveLF        = LF_ASLF;
  274.  
  275.     Config -> SetArchivedBit    = FALSE;
  276.  
  277.     Config -> KeyMapName[0]        = 0;
  278.  
  279.     Config -> OpenFastMacroPanel    = FALSE;
  280.  
  281.     Config -> PassThrough        = FALSE;
  282.  
  283.     Config -> SystemBeep        = FALSE;
  284.  
  285.     Config -> Pad            = FALSE;
  286.  
  287.     Config -> AnswerBack[0]        = 0;
  288.  
  289.     Config -> Pad2            = FALSE;
  290. }
  291.  
  292. VOID
  293. RemoveDialEntry(LONG Entry)
  294. {
  295.     LONG Count = Phonebook[Entry] -> Count,i;
  296.  
  297.     for(i = 0 ; i < NumPhoneEntries ; i++)
  298.     {
  299.         if(Phonebook[i] -> Count > Count)
  300.             SPrintf(Phonebook[i] -> Node -> LocalName,"%3ld - %s",Phonebook[i] -> Count--,Phonebook[i] -> Name);
  301.     }
  302.  
  303.     Phonebook[Entry] -> Count = -1;
  304.  
  305.     SPrintf(Phonebook[Entry] -> Node -> LocalName,"      %s",Phonebook[Entry] -> Name);
  306. }
  307.  
  308. VOID
  309. RemoveDialNode(struct PhoneNode *Node)
  310. {
  311.     LONG Count = Node -> Entry -> Count,i;
  312.  
  313.     for(i = 0 ; i < NumPhoneEntries ; i++)
  314.     {
  315.         if(Phonebook[i] -> Count > Count)
  316.             SPrintf(Phonebook[i] -> Node -> LocalName,"%3ld - %s",Phonebook[i] -> Count--,Phonebook[i] -> Name);
  317.     }
  318.  
  319.     Node -> Entry -> Count = -1;
  320.  
  321.     SPrintf(Node -> LocalName,"      %s",Node -> Entry -> Name);
  322. }
  323.  
  324. VOID
  325. SortToList(struct PhoneNode *PhoneNode)
  326. {
  327.     if(!DialList)
  328.     {
  329.         if(DialList = (struct List *)AllocVec(sizeof(struct List),MEMF_ANY|MEMF_CLEAR))
  330.             NewList(DialList);
  331.     }
  332.  
  333.     if(DialList)
  334.     {
  335.         struct PhoneNode *Node = (struct PhoneNode *)DialList -> lh_Head,*NewNode;
  336.  
  337.         if(NewNode = (struct PhoneNode *)AllocVec(sizeof(struct PhoneNode),MEMF_ANY))
  338.         {
  339.             CopyMem(PhoneNode,NewNode,sizeof(struct PhoneNode));
  340.  
  341.             while(Node -> VanillaNode . ln_Succ)
  342.             {
  343.                 if(Node -> Entry -> Count > NewNode -> Entry -> Count)
  344.                 {
  345.                     if(Node == (struct NewNode *)DialList -> lh_Head)
  346.                         AddHead(DialList,&NewNode -> VanillaNode);
  347.                     else
  348.                         Insert(DialList,&NewNode -> VanillaNode,Node -> VanillaNode . ln_Pred);
  349.  
  350.                     return;
  351.                 }
  352.  
  353.                 Node = (struct PhoneNode *)Node -> VanillaNode . ln_Succ;
  354.             }
  355.  
  356.             AddTail(DialList,&NewNode -> VanillaNode);
  357.         }
  358.     }
  359. }
  360.  
  361. VOID
  362. FreeDialList()
  363. {
  364.     if(DialList)
  365.     {
  366.         struct PhoneNode *NextNode,*SubNode;
  367.  
  368.         SubNode = (struct PhoneNode *)DialList -> lh_Head;
  369.  
  370.         while(SubNode -> VanillaNode . ln_Succ)
  371.         {
  372.             NextNode = (struct PhoneNode *)SubNode -> VanillaNode . ln_Succ;
  373.  
  374.             FreeVec(SubNode);
  375.  
  376.             SubNode = NextNode;
  377.         }
  378.  
  379.         FreeVec(DialList);
  380.  
  381.         DialList = NULL;
  382.     }
  383. }
  384.  
  385.     /* CreatePhoneList():
  386.      *
  387.      *    Turn the array of pointers to phonebook entries into
  388.      *    a linked standard Amiga List (gadtools needs this).
  389.      */
  390.  
  391. struct List *
  392. CreatePhoneList()
  393. {
  394.     struct List        *PhoneList;
  395.     struct PhoneNode    *PhoneNode;
  396.     LONG             i;
  397.  
  398.     if(Phonebook && NumPhoneEntries)
  399.     {
  400.         if(PhoneList = (struct List *)AllocVec(sizeof(struct List) + NumPhoneEntries * sizeof(struct PhoneNode),MEMF_ANY|MEMF_CLEAR))
  401.         {
  402.             NewList(PhoneList);
  403.  
  404.             PhoneNode = (struct PhoneNode *)(PhoneList + 1);
  405.  
  406.             for(i = 0 ; i < NumPhoneEntries ; i++)
  407.             {
  408.                 if(Phonebook[i] -> Count != -1)
  409.                     SPrintf(PhoneNode[i] . LocalName,"%3ld - %s",Phonebook[i] -> Count + 1,Phonebook[i] -> Name);
  410.                 else
  411.                     SPrintf(PhoneNode[i] . LocalName,"      %s",Phonebook[i] -> Name);
  412.  
  413.                 PhoneNode[i] . VanillaNode . ln_Name = PhoneNode[i] . LocalName;
  414.  
  415.                 Phonebook[i] -> Node = &PhoneNode[i];
  416.  
  417.                 PhoneNode[i] . Entry = Phonebook[i];
  418.  
  419.                 AddTail(PhoneList,&PhoneNode[i]);
  420.             }
  421.  
  422.             return(PhoneList);
  423.         }
  424.     }
  425.     else
  426.     {
  427.         if(PhoneList = (struct List *)AllocVec(sizeof(struct List),MEMF_ANY|MEMF_CLEAR))
  428.         {
  429.             NewList(PhoneList);
  430.  
  431.             return(PhoneList);
  432.         }
  433.     }
  434.  
  435.     return(NULL);
  436. }
  437.  
  438.     /* DeletePhoneList(struct List *PhoneList):
  439.      *
  440.      *    Delete the entries listed in the Amiga List
  441.      *    created by the routine above.
  442.      */
  443.  
  444. VOID
  445. DeletePhoneList(struct List *PhoneList)
  446. {
  447.     if(PhoneList)
  448.     {
  449.         FreeVec(PhoneList);
  450.  
  451.         PhoneList = NULL;
  452.     }
  453. }
  454.  
  455.     /* Compare(struct PhoneEntry **A,struct PhoneEntry **B):
  456.      *
  457.      *    Comparison subroutine required by the QuickSort
  458.      *    call below.     
  459.      */
  460.  
  461. STATIC LONG __stdargs
  462. Compare(struct PhoneEntry **A,struct PhoneEntry **B)
  463. {
  464.         /* Has entry A been selected? */
  465.  
  466.     if((*A) -> Count == -1)
  467.     {
  468.             /* If entry B isn't selected either, compare the
  469.              * names lexically, else entry B is supposed
  470.              * to be `smaller' than entry A.
  471.              */
  472.  
  473.         if((*B) -> Count == -1)
  474.             return(Stricmp((*A) -> Name,(*B) -> Name));
  475.         else
  476.             return(1);
  477.     }
  478.     else
  479.     {
  480.             /* If entry B isn't selected, entry A is supposed
  481.              * to be `smaller' than entry B, else return
  482.              * the difference between both entries.
  483.              */
  484.  
  485.         if((*B) -> Count == -1)
  486.             return(-1);
  487.         else
  488.             return((*A) -> Count - (*B) -> Count);
  489.     }
  490. }
  491.  
  492.     /* SortPhoneEntries():
  493.      *
  494.      *    Sorts the current phone list array in ascending order.
  495.      */
  496.  
  497. VOID
  498. SortPhoneEntries()
  499. {
  500.     qsort(Phonebook,NumPhoneEntries,sizeof(struct PhoneEntry *),Compare);
  501. }
  502.  
  503. VOID
  504. FreeTimeDateList(struct List *List)
  505. {
  506.     struct Node *Node,*NextNode;
  507.  
  508.     Node = List -> lh_Head;
  509.  
  510.     while(Node -> ln_Succ)
  511.     {
  512.         NextNode = Node -> ln_Succ;
  513.  
  514.         Remove(Node);
  515.  
  516.         FreeVec(Node);
  517.  
  518.         Node = NextNode;
  519.     }
  520. }
  521.  
  522. VOID
  523. CopyTimeDateList(struct List *From,struct List *To,BYTE SkipFirst)
  524. {
  525.     struct TimeDateNode *FromNode,*ToNode;
  526.  
  527.     FromNode = (struct TimeDateNode *)From -> lh_Head;
  528.  
  529.     if(SkipFirst)
  530.         FromNode = (struct TimeDateNode *)FromNode -> VanillaNode . ln_Succ;
  531.  
  532.     while(FromNode -> VanillaNode . ln_Succ)
  533.     {
  534.         if(ToNode = (struct TimeDateNode *)AllocVec(sizeof(struct TimeDateNode),MEMF_ANY))
  535.         {
  536.             CopyMem(FromNode,ToNode,sizeof(struct TimeDateNode));
  537.  
  538.             ToNode -> VanillaNode . ln_Name = ToNode -> Buffer;
  539.  
  540.             AddTail(To,&ToNode -> VanillaNode);
  541.         }
  542.  
  543.         FromNode = (struct TimeDateNode *)FromNode -> VanillaNode . ln_Succ;
  544.     }
  545. }
  546.  
  547. VOID
  548. AdaptTimeDateNode(struct TimeDateNode *Node)
  549. {
  550.     UBYTE *Comment = Node -> TimeDate . Comment[0] ? Node -> TimeDate . Comment : LocaleString(MSG_TERMPHONE_NO_COMMENT_TXT);
  551.  
  552.     if(Node -> TimeDate . Month == -1)
  553.     {
  554.         if(Node -> TimeDate . Day == -1)
  555.             strcpy(Node -> Buffer,LocaleString(MSG_TERMPHONE_STANDARD_SETTINGS_TXT));
  556.         else
  557.             SPrintf(Node -> Buffer,LocaleString(MSG_TERMPHONE_DAYS_TXT),Comment);
  558.     }
  559.     else
  560.         SPrintf(Node -> Buffer,"%2ld %s » %s",Node -> TimeDate . Day,LocaleString(MSG_TERMPHONE_JAN_TXT + Node -> TimeDate . Month),Comment);
  561. }
  562.  
  563. struct TimeDateNode *
  564. CreateTimeDateNode(BYTE Month,BYTE Day,UBYTE *Comment)
  565. {
  566.     struct TimeDateNode *Node;
  567.  
  568.     if(Node = (struct TimeDateNode *)AllocVec(sizeof(struct TimeDateNode),MEMF_ANY|MEMF_CLEAR))
  569.     {
  570.         Node -> VanillaNode . ln_Name        = Node -> Buffer;
  571.  
  572.         Node -> TimeDate . Month        = Month;
  573.         Node -> TimeDate . Day            = Day;
  574.  
  575.         Node -> TimeDate . PayPerUnit[0]    = 23;
  576.         Node -> TimeDate . PayPerUnit[1]    = 23;
  577.  
  578.         Node -> TimeDate . SecPerUnit[0]    =  6 * 60;
  579.         Node -> TimeDate . SecPerUnit[1]    = 12 * 60;
  580.  
  581.         Node -> TimeDate . TimeOfDay[0]        =  48;
  582.         Node -> TimeDate . TimeOfDay[1]        = 108;
  583.  
  584.         strcpy(Node -> TimeDate . Comment,Comment);
  585.  
  586.         AdaptTimeDateNode(Node);
  587.     }
  588.  
  589.     return(Node);
  590. }
  591.  
  592.     /* RemPhoneEntry(LONG Num):
  593.      *
  594.      *    Remove a given entry from the phone book.
  595.      */
  596.  
  597. VOID
  598. RemPhoneEntry(LONG Num)
  599. {
  600.     struct PhoneEntry    *Entry;
  601.     LONG             i;
  602.  
  603.     Entry = Phonebook[Num];
  604.  
  605.     for(i = Num ; i < NumPhoneEntries ; i++)
  606.         Phonebook[i] = Phonebook[i + 1];
  607.  
  608.     Phonebook[NumPhoneEntries--] = NULL;
  609.  
  610.     FreeTimeDateList((struct List *)&Entry -> TimeDateList);
  611.  
  612.     FreeVec(Entry);
  613. }
  614.  
  615.     /* NewPhoneEntry():
  616.      *
  617.      *    Create a new phone book entry with default values and
  618.      *    add it to the array. Expand the phone book if necessary.
  619.      */
  620.  
  621. BYTE
  622. NewPhoneEntry()
  623. {
  624.     struct PhoneEntry    **PrivatePhonebook;
  625.     LONG             PrivatePhoneSize;
  626.     LONG             i;
  627.  
  628.         /* The phone book is filled `to the brim', so let's expand
  629.          * it.
  630.          */
  631.  
  632.     if(NumPhoneEntries + 1 > PhoneSize)
  633.     {
  634.             /* Allocate another phone book. */
  635.  
  636.         if(PrivatePhonebook = CreatePhonebook(PhoneSize + 1,&PrivatePhoneSize,FALSE))
  637.         {
  638.                 /* Copy the data. */
  639.  
  640.             if(Phonebook && PhoneSize)
  641.             {
  642.                 for(i = 0 ; i < PhoneSize ; i++)
  643.                     PrivatePhonebook[i] = Phonebook[i];
  644.  
  645.                     /* Remove the old phonebook. */
  646.  
  647.                 DeletePhonebook(Phonebook,PhoneSize,FALSE);
  648.             }
  649.  
  650.                 /* Assign the new pointers. */
  651.  
  652.             Phonebook = PrivatePhonebook;
  653.             PhoneSize = PrivatePhoneSize;
  654.         }
  655.         else
  656.             return(FALSE);
  657.     }
  658.  
  659.         /* Allocate another entry and add it to the phone book. */
  660.  
  661.     if(Phonebook[NumPhoneEntries] = (struct PhoneEntry *)AllocVec(sizeof(struct PhoneEntry),MEMF_ANY|MEMF_CLEAR))
  662.     {
  663.         struct TimeDateNode *TimeDateNode;
  664.  
  665.         strcpy(Phonebook[NumPhoneEntries] -> Name,LocaleString(MSG_TERMPHONE_UNUSED_ENTRY_TXT));
  666.  
  667.         CopyMem(&Config,&Phonebook[NumPhoneEntries] -> Config,sizeof(struct Configuration));
  668.  
  669.         Phonebook[NumPhoneEntries] -> Count        = -1;
  670.  
  671.         NewList((struct List *)&Phonebook[NumPhoneEntries] -> TimeDateList);
  672.  
  673.         if(TimeDateNode = CreateTimeDateNode(-1,-1,""))
  674.             AddTail((struct List *)&Phonebook[NumPhoneEntries] -> TimeDateList,&TimeDateNode -> VanillaNode);
  675.  
  676.         NumPhoneEntries++;
  677.  
  678.         return(TRUE);
  679.     }
  680.  
  681.     return(FALSE);
  682. }
  683.  
  684.     /* CreatePhonebook(LONG Size,LONG *AllocSize,BYTE CreateEntries):
  685.      *
  686.      *    Create a new phone entry array (so-called phone book).
  687.      */
  688.  
  689. struct PhoneEntry **
  690. CreatePhonebook(LONG Size,LONG *AllocSize,BYTE CreateEntries)
  691. {
  692.     struct PhoneEntry **PhoneEntry = NULL;
  693.  
  694.     if(Size)
  695.     {
  696.             /* Round the number of phone entries to a
  697.              * multiple of eight.
  698.              */
  699.  
  700.         *AllocSize = (((Size + 7) >> 3) << 3);
  701.  
  702.             /* Create the list of pointers. */
  703.  
  704.         if(PhoneEntry = (struct PhoneEntry **)AllocVec(*AllocSize * sizeof(struct PhoneEntry *),MEMF_ANY|MEMF_CLEAR))
  705.         {
  706.                 /* And create some entries if necessary. */
  707.  
  708.             if(CreateEntries)
  709.             {
  710.                 LONG i;
  711.  
  712.                 for(i = 0 ; i < Size ; i++)
  713.                 {
  714.                     if(!(PhoneEntry[i] = (struct PhoneEntry *)AllocVec(sizeof(struct PhoneEntry),MEMF_ANY|MEMF_CLEAR)))
  715.                     {
  716.                         LONG j;
  717.  
  718.                         for(j = 0 ; j < i ; j++)
  719.                             FreeVec(PhoneEntry[j]);
  720.  
  721.                         FreeVec(PhoneEntry);
  722.  
  723.                         return(NULL);
  724.                     }
  725.                     else
  726.                         NewList((struct List *)&PhoneEntry[i] -> TimeDateList);
  727.                 }
  728.             }
  729.         }
  730.     }
  731.  
  732.     return(PhoneEntry);
  733. }
  734.  
  735.     /* DeletePhonebook(struct PhoneEntry **PhoneBook,LONG Size,BYTE FreeEntries):
  736.      *
  737.      *    Deallocates a given phone book and its entries if necessary.
  738.      */
  739.  
  740. VOID
  741. DeletePhonebook(struct PhoneEntry **Phonebook,LONG Size,BYTE FreeEntries)
  742. {
  743.     if(FreeEntries)
  744.     {
  745.         LONG i;
  746.  
  747.         for(i = 0 ; i < Size ; i++)
  748.         {
  749.             if(Phonebook[i])
  750.             {
  751.                 FreeTimeDateList((struct List *)&Phonebook[i] -> TimeDateList);
  752.  
  753.                 FreeVec(Phonebook[i]);
  754.             }
  755.         }
  756.     }
  757.  
  758.     FreeVec(Phonebook);
  759. }
  760.  
  761.     /* SavePhonebook(UBYTE *Name):
  762.      *
  763.      *    Save the current phone book to a disk file.
  764.      */
  765.  
  766. BYTE
  767. SavePhonebook(UBYTE *Name)
  768. {
  769.     struct IFFHandle    *Handle;
  770.     BYTE             Success = FALSE;
  771.  
  772.     if(Phonebook && NumPhoneEntries)
  773.     {
  774.         if(Handle = (struct IFFHandle *)AllocIFF())
  775.         {
  776.             if(Handle -> iff_Stream = Open(Name,MODE_NEWFILE))
  777.             {
  778.                 InitIFFasDOS(Handle);
  779.  
  780.                 if(!OpenIFF(Handle,IFFF_WRITE))
  781.                 {
  782.                     if(!PushChunk(Handle,'TERM',ID_CAT,IFFSIZE_UNKNOWN))
  783.                     {
  784.                         if(!PushChunk(Handle,'TERM',ID_FORM,IFFSIZE_UNKNOWN))
  785.                         {
  786.                             if(!PushChunk(Handle,0,'VERS',IFFSIZE_UNKNOWN))
  787.                             {
  788.                                 struct TermInfo TermInfo;
  789.  
  790.                                 TermInfo . Version    = TermVersion;
  791.                                 TermInfo . Revision    = TermRevision;
  792.  
  793.                                 if(WriteChunkBytes(Handle,&TermInfo,sizeof(struct TermInfo)) == sizeof(struct TermInfo))
  794.                                 {
  795.                                     if(PopChunk(Handle))
  796.                                         Success = FALSE;
  797.                                     else
  798.                                     {
  799.                                         UBYTE *TempBuffer = NULL;
  800.  
  801.                                         if(PhonePasswordUsed)
  802.                                         {
  803.                                             if(!PushChunk(Handle,0,'PSWD',20))
  804.                                             {
  805.                                                 Success = TRUE;
  806.  
  807.                                                 if(WriteChunkBytes(Handle,PhonePassword,20) != 20)
  808.                                                     Success = FALSE;
  809.  
  810.                                                 if(PopChunk(Handle))
  811.                                                     Success = FALSE;
  812.  
  813.                                                 if(Success)
  814.                                                 {
  815.                                                     if(!(TempBuffer = AllocVec(RAWSIZE,MEMF_ANY)))
  816.                                                         Success = FALSE;
  817.                                                 }
  818.                                             }
  819.                                         }
  820.                                         else
  821.                                             Success = TRUE;
  822.  
  823.                                         if(Success)
  824.                                         {
  825.                                             Success = FALSE;
  826.  
  827.                                             if(!PushChunk(Handle,0,'DIAL',IFFSIZE_UNKNOWN))
  828.                                             {
  829.                                                 if(WriteChunkBytes(Handle,&NumPhoneEntries,sizeof(LONG)) == sizeof(LONG))
  830.                                                 {
  831.                                                     if(PopChunk(Handle))
  832.                                                         Success = FALSE;
  833.                                                     else
  834.                                                     {
  835.                                                         if(PopChunk(Handle))
  836.                                                             Success = FALSE;
  837.                                                         else
  838.                                                         {
  839.                                                             LONG i;
  840.  
  841.                                                             for(i = 0 ; i < NumPhoneEntries ; i++)
  842.                                                             {
  843.                                                                 if(!PushChunk(Handle,'TERM',ID_FORM,IFFSIZE_UNKNOWN))
  844.                                                                 {
  845.                                                                     if(!PushChunk(Handle,0,'PREF',IFFSIZE_UNKNOWN))
  846.                                                                     {
  847.                                                                         if(TempBuffer)
  848.                                                                         {
  849.                                                                             Encrypt((UBYTE *)Phonebook[i] -> Name,RAWSIZE,TempBuffer,PhonePassword,20,TRUE);
  850.  
  851.                                                                             if(WriteChunkBytes(Handle,TempBuffer,RAWSIZE) != RAWSIZE)
  852.                                                                             {
  853.                                                                                 Success = FALSE;
  854.  
  855.                                                                                 break;
  856.                                                                             }
  857.                                                                             else
  858.                                                                                 Success = TRUE;
  859.                                                                         }
  860.                                                                         else
  861.                                                                         {
  862.                                                                             if(WriteChunkBytes(Handle,Phonebook[i] -> Name,RAWSIZE) != RAWSIZE)
  863.                                                                             {
  864.                                                                                 Success = FALSE;
  865.  
  866.                                                                                 break;
  867.                                                                             }
  868.                                                                             else
  869.                                                                                 Success = TRUE;
  870.                                                                         }
  871.  
  872.                                                                         if(PopChunk(Handle))
  873.                                                                         {
  874.                                                                             Success = FALSE;
  875.  
  876.                                                                             break;
  877.                                                                         }
  878.                                                                     }
  879.  
  880.                                                                     if(Success)
  881.                                                                     {
  882.                                                                         if(!PushChunk(Handle,0,'TIME',IFFSIZE_UNKNOWN))
  883.                                                                         {
  884.                                                                             struct TimeDateNode *TimeDateNode;
  885.  
  886.                                                                             TimeDateNode = (struct TimeDateNode *)Phonebook[i] -> TimeDateList . mlh_Head;
  887.  
  888.                                                                             while(TimeDateNode -> VanillaNode . ln_Succ)
  889.                                                                             {
  890.                                                                                 if(TempBuffer)
  891.                                                                                 {
  892.                                                                                     Encrypt((UBYTE *)&TimeDateNode -> TimeDate,sizeof(struct TimeDate),TempBuffer,PhonePassword,20,TRUE);
  893.  
  894.                                                                                     if(WriteChunkBytes(Handle,TempBuffer,sizeof(struct TimeDate)) != sizeof(struct TimeDate))
  895.                                                                                     {
  896.                                                                                         Success = FALSE;
  897.  
  898.                                                                                         break;
  899.                                                                                     }
  900.                                                                                 }
  901.                                                                                 else
  902.                                                                                 {
  903.                                                                                     if(WriteChunkBytes(Handle,&TimeDateNode -> TimeDate,sizeof(struct TimeDate)) != sizeof(struct TimeDate))
  904.                                                                                     {
  905.                                                                                         Success = FALSE;
  906.  
  907.                                                                                         break;
  908.                                                                                     }
  909.                                                                                 }
  910.  
  911.                                                                                 TimeDateNode = (struct TimeDateNode *)TimeDateNode -> VanillaNode . ln_Succ;
  912.                                                                             }
  913.  
  914.                                                                             if(PopChunk(Handle))
  915.                                                                                 Success = FALSE;
  916.                                                                         }
  917.                                                                         else
  918.                                                                             Success = FALSE;
  919.                                                                     }
  920.  
  921.                                                                     if(PopChunk(Handle))
  922.                                                                     {
  923.                                                                         Success = FALSE;
  924.  
  925.                                                                         break;
  926.                                                                     }
  927.                                                                 }
  928.                                                             }
  929.                                                         }
  930.                                                     }
  931.                                                 }
  932.                                             }
  933.  
  934.                                             if(TempBuffer)
  935.                                                 FreeVec(TempBuffer);
  936.                                         }
  937.                                     }
  938.                                 }
  939.                             }
  940.                         }
  941.  
  942.                         if(PopChunk(Handle))
  943.                             Success = FALSE;
  944.                     }
  945.  
  946.                     CloseIFF(Handle);
  947.                 }
  948.  
  949.                 Close(Handle -> iff_Stream);
  950.             }
  951.  
  952.             FreeIFF(Handle);
  953.         }
  954.  
  955.         if(Success)
  956.             SetProtection(Name,FIBF_EXECUTE);
  957.         else
  958.             DeleteFile(Name);
  959.     }
  960.  
  961.     return(Success);
  962. }
  963.  
  964.     /* OldLoadPhonebook(UBYTE *Name):
  965.      *
  966.      *    Restore a phone book from a disk file (old version).
  967.      */
  968.  
  969. STATIC BYTE __regargs
  970. OldLoadPhonebook(UBYTE *Name)
  971. {
  972.     struct PhoneEntry    **PrivatePhonebook;
  973.     LONG             PrivatePhoneSize;
  974.     LONG             Size,i;
  975.     struct IFFHandle    *Handle;
  976.     BYTE             Success = FALSE;
  977.     struct StoredProperty    *Prop;
  978.     struct TermInfo        *TermInfo;
  979.  
  980.     if(Handle = AllocIFF())
  981.     {
  982.         if(Handle -> iff_Stream = Open(Name,MODE_OLDFILE))
  983.         {
  984.             InitIFFasDOS(Handle);
  985.  
  986.             if(!OpenIFF(Handle,IFFF_READ))
  987.             {
  988.                 if(!PropChunks(Handle,&VersionProps[0],1))
  989.                 {
  990.                     if(!StopChunk(Handle,'TERM','DIAL'))
  991.                     {
  992.                         if(!ParseIFF(Handle,IFFPARSE_SCAN))
  993.                         {
  994.                             if(Prop = FindProp(Handle,'TERM','VERS'))
  995.                             {
  996.                                 TermInfo = (struct TermInfo *)Prop -> sp_Data;
  997.  
  998.                                 if(TermInfo -> Version == 1 && TermInfo -> Revision >= 6)
  999.                                 {
  1000.                                     if(ReadChunkRecords(Handle,&Size,sizeof(LONG),1))
  1001.                                     {
  1002.                                         if(Size)
  1003.                                         {
  1004.                                             if(PrivatePhonebook = CreatePhonebook(Size,&PrivatePhoneSize,TRUE))
  1005.                                             {
  1006.                                                 struct ContextNode    *Chunk;
  1007.                                                 LONG             ItemSize;
  1008.                                                 struct TimeDateNode    *TimeDateNode;
  1009.  
  1010.                                                 Chunk = CurrentChunk(Handle);
  1011.  
  1012.                                                 ItemSize = Chunk -> cn_Size / Size;
  1013.  
  1014.                                                 for(i = 0 ; i < Size ; i++)
  1015.                                                 {
  1016.                                                     SetPrefToDefaults(&PrivatePhonebook[i] -> Config,NULL);
  1017.  
  1018.                                                     if(ReadChunkRecords(Handle,PrivatePhonebook[i] -> Name,ItemSize,1))
  1019.                                                     {
  1020.                                                         PrivatePhonebook[i] -> Count = -1;
  1021.  
  1022.                                                         if(strlen(PrivatePhonebook[i] -> Password) > 19)
  1023.                                                         {
  1024.                                                             PrivatePhonebook[i] -> Password[19] = 0;
  1025.                                                             PrivatePhonebook[i] -> UserName[ 0] = 0;
  1026.                                                         }
  1027.  
  1028.                                                         if(TimeDateNode = CreateTimeDateNode(-1,-1,""))
  1029.                                                         {
  1030.                                                             TimeDateNode -> TimeDate . PayPerUnit[0]    = PrivatePhonebook[i] -> PayPerUnit[0];
  1031.                                                             TimeDateNode -> TimeDate . PayPerUnit[1]    = PrivatePhonebook[i] -> PayPerUnit[1];
  1032.  
  1033.                                                             TimeDateNode -> TimeDate . SecPerUnit[0]    = PrivatePhonebook[i] -> SecPerUnit[0];
  1034.                                                             TimeDateNode -> TimeDate . SecPerUnit[1]    = PrivatePhonebook[i] -> SecPerUnit[1];
  1035.  
  1036.                                                             TimeDateNode -> TimeDate . TimeOfDay[0]    = PrivatePhonebook[i] -> TimeOfDay[0];
  1037.                                                             TimeDateNode -> TimeDate . TimeOfDay[1]    = PrivatePhonebook[i] -> TimeOfDay[1];
  1038.  
  1039.                                                             AddTail((struct List *)&PrivatePhonebook[i] -> TimeDateList,&TimeDateNode -> VanillaNode);
  1040.                                                         }
  1041.                                                     }
  1042.                                                     else
  1043.                                                     {
  1044.                                                         if(i)
  1045.                                                             Size = i - 1;
  1046.                                                         else
  1047.                                                             Size = 0;
  1048.  
  1049.                                                         break;
  1050.                                                     }
  1051.                                                 }
  1052.  
  1053.                                                 if(Size)
  1054.                                                 {
  1055.                                                     if(Phonebook)
  1056.                                                         DeletePhonebook(Phonebook,PhoneSize,TRUE);
  1057.  
  1058.                                                     Phonebook = PrivatePhonebook;
  1059.                                                     PhoneSize = PrivatePhoneSize;
  1060.  
  1061.                                                     NumPhoneEntries = Size;
  1062.  
  1063.                                                     Success = TRUE;
  1064.                                                 }
  1065.                                                 else
  1066.                                                 {
  1067.                                                     DeletePhonebook(PrivatePhonebook,PrivatePhoneSize,TRUE);
  1068.  
  1069.                                                     Success = FALSE;
  1070.                                                 }
  1071.  
  1072.                                                 FreeDialList();
  1073.                                             }
  1074.                                         }
  1075.                                     }
  1076.                                 }
  1077.                             }
  1078.                         }
  1079.                     }
  1080.                 }
  1081.  
  1082.                 CloseIFF(Handle);
  1083.             }
  1084.  
  1085.             Close(Handle -> iff_Stream);
  1086.         }
  1087.  
  1088.         FreeIFF(Handle);
  1089.     }
  1090.  
  1091.     return(Success);
  1092. }
  1093.  
  1094.     /* LoadPhonebook(UBYTE *Name):
  1095.      *
  1096.      *    Restore a phone book from a disk file.
  1097.      */
  1098.  
  1099. BYTE
  1100. LoadPhonebook(UBYTE *Name)
  1101. {
  1102.     STATIC ULONG Stops[2 * 6] =
  1103.     {
  1104.         'TERM','VERS',
  1105.         'TERM','DIAL',
  1106.         'TERM','PREF',
  1107.         'TERM','TIME',
  1108.         'TERM','PASS',
  1109.         'TERM','PSWD'
  1110.     };
  1111.  
  1112.     struct PhoneEntry    **PrivatePhonebook;
  1113.     LONG             PrivatePhoneSize = 0;
  1114.     LONG             Size = 0,i,j,Last = -1;
  1115.     struct IFFHandle    *Handle;
  1116.     BYTE             Success = FALSE;
  1117.     struct ContextNode    *Chunk;
  1118.     BYTE             UseOld        = FALSE,
  1119.                  LastHadTime    = TRUE,
  1120.                  HadPassword    = FALSE,
  1121.                  NewStyle    = TRUE;
  1122.     struct TimeDateNode    *TimeDateNode;
  1123.  
  1124.     if(Handle = AllocIFF())
  1125.     {
  1126.         if(Handle -> iff_Stream = Open(Name,MODE_OLDFILE))
  1127.         {
  1128.             InitIFFasDOS(Handle);
  1129.  
  1130.             if(!OpenIFF(Handle,IFFF_READ))
  1131.             {
  1132.                 if(!StopChunks(Handle,&Stops[0],6))
  1133.                 {
  1134.                     while(!ParseIFF(Handle,IFFPARSE_SCAN))
  1135.                     {
  1136.                         Chunk = CurrentChunk(Handle);
  1137.  
  1138.                         if(Chunk -> cn_ID == 'VERS')
  1139.                         {
  1140.                             struct TermInfo TermInfo;
  1141.  
  1142.                             if(ReadChunkBytes(Handle,&TermInfo,sizeof(struct TermInfo)) == sizeof(struct TermInfo))
  1143.                             {
  1144.                                 if(TermInfo . Version == 1 && TermInfo . Revision < 9)
  1145.                                 {
  1146.                                     UseOld = TRUE;
  1147.  
  1148.                                     break;
  1149.                                 }
  1150.  
  1151.                                 if((TermInfo . Version > TermVersion) || (TermInfo . Version == TermVersion && TermInfo . Revision > TermRevision) || (TermInfo . Version == 1 && TermInfo . Revision < 6))
  1152.                                     break;
  1153.                             }
  1154.                             else
  1155.                                 break;
  1156.                         }
  1157.  
  1158.                         if(Chunk -> cn_ID == 'PASS')
  1159.                         {
  1160.                             UBYTE DummyBuffer[20];
  1161.  
  1162.                             HadPassword = TRUE;
  1163.  
  1164.                             if(ReadChunkBytes(Handle,DummyBuffer,20) == 20)
  1165.                             {
  1166.                                 if(PhonePasswordUsed)
  1167.                                 {
  1168.                                     if(!memcmp(PhonePassword,DummyBuffer,20))
  1169.                                         continue;
  1170.                                 }
  1171.  
  1172.                                 memset(SharedBuffer,0,20);
  1173.  
  1174.                                 if(CryptPanel(SharedBuffer))
  1175.                                 {
  1176.                                     UBYTE AnotherBuffer[20];
  1177.  
  1178.                                     Encrypt(SharedBuffer,20,AnotherBuffer,SharedBuffer,20,NewStyle = FALSE);
  1179.  
  1180.                                     if(!memcmp(DummyBuffer,AnotherBuffer,20))
  1181.                                     {
  1182.                                         memcpy(PhonePassword,DummyBuffer,20);
  1183.  
  1184.                                         PhonePasswordUsed = TRUE;
  1185.  
  1186.                                         continue;
  1187.                                     }
  1188.                                     else
  1189.                                     {
  1190.                                         MyEasyRequest(Window,LocaleString(MSG_TERMPHONE_WRONG_PASSWORD_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Name);
  1191.  
  1192.                                         break;
  1193.                                     }
  1194.                                 }
  1195.                                 else
  1196.                                     break;
  1197.                             }
  1198.                             else
  1199.                                 break;
  1200.                         }
  1201.  
  1202.                         if(Chunk -> cn_ID == 'PSWD')
  1203.                         {
  1204.                             UBYTE DummyBuffer[20];
  1205.  
  1206.                             HadPassword = TRUE;
  1207.  
  1208.                             if(ReadChunkBytes(Handle,DummyBuffer,20) == 20)
  1209.                             {
  1210.                                 if(PhonePasswordUsed)
  1211.                                 {
  1212.                                     if(!memcmp(PhonePassword,DummyBuffer,20))
  1213.                                         continue;
  1214.                                 }
  1215.  
  1216.                                 memset(SharedBuffer,0,20);
  1217.  
  1218.                                 if(CryptPanel(SharedBuffer))
  1219.                                 {
  1220.                                     UBYTE AnotherBuffer[20];
  1221.  
  1222.                                     Encrypt(SharedBuffer,20,AnotherBuffer,SharedBuffer,strlen(SharedBuffer),NewStyle = TRUE);
  1223.  
  1224.                                     if(!memcmp(DummyBuffer,AnotherBuffer,20))
  1225.                                     {
  1226.                                         memcpy(PhonePassword,DummyBuffer,20);
  1227.  
  1228.                                         PhonePasswordUsed = TRUE;
  1229.  
  1230.                                         continue;
  1231.                                     }
  1232.                                     else
  1233.                                     {
  1234.                                         MyEasyRequest(Window,LocaleString(MSG_TERMPHONE_WRONG_PASSWORD_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Name);
  1235.  
  1236.                                         break;
  1237.                                     }
  1238.                                 }
  1239.                                 else
  1240.                                     break;
  1241.                             }
  1242.                             else
  1243.                                 break;
  1244.                         }
  1245.  
  1246.                         if(Chunk -> cn_ID == 'DIAL')
  1247.                         {
  1248.                             if(ReadChunkBytes(Handle,&Size,sizeof(LONG)) == sizeof(LONG))
  1249.                             {
  1250.                                 i = 0;
  1251.  
  1252.                                 if(!(PrivatePhonebook = CreatePhonebook(Size,&PrivatePhoneSize,TRUE)))
  1253.                                     break;
  1254.                             }
  1255.                             else
  1256.                                 break;
  1257.                         }
  1258.  
  1259.                         if(Chunk -> cn_ID == 'PREF')
  1260.                         {
  1261.                             if(!LastHadTime && Last != -1)
  1262.                             {
  1263.                                 if(strlen(PrivatePhonebook[i] -> Password) > 19)
  1264.                                 {
  1265.                                     PrivatePhonebook[i] -> Password[19] = 0;
  1266.                                     PrivatePhonebook[i] -> UserName[ 0] = 0;
  1267.                                 }
  1268.  
  1269.                                 if(TimeDateNode = CreateTimeDateNode(-1,-1,""))
  1270.                                 {
  1271.                                     TimeDateNode -> TimeDate . PayPerUnit[0]    = PrivatePhonebook[Last] -> PayPerUnit[0];
  1272.                                     TimeDateNode -> TimeDate . PayPerUnit[1]    = PrivatePhonebook[Last] -> PayPerUnit[1];
  1273.  
  1274.                                     TimeDateNode -> TimeDate . SecPerUnit[0]    = PrivatePhonebook[Last] -> SecPerUnit[0];
  1275.                                     TimeDateNode -> TimeDate . SecPerUnit[1]    = PrivatePhonebook[Last] -> SecPerUnit[1];
  1276.  
  1277.                                     TimeDateNode -> TimeDate . TimeOfDay[0]    = PrivatePhonebook[Last] -> TimeOfDay[0];
  1278.                                     TimeDateNode -> TimeDate . TimeOfDay[1]    = PrivatePhonebook[Last] -> TimeOfDay[1];
  1279.  
  1280.                                     AddTail((struct List *)&PrivatePhonebook[Last] -> TimeDateList,&TimeDateNode -> VanillaNode);
  1281.                                 }
  1282.                             }
  1283.  
  1284.                             if(Size && i < Size)
  1285.                             {
  1286.                                 WORD LastSize = sizeof(struct PhoneEntry);
  1287.  
  1288.                                 PhonePasswordUsed = HadPassword;
  1289.  
  1290.                                 if(Chunk -> cn_Size < LastSize)
  1291.                                     LastSize = Chunk -> cn_Size;
  1292.  
  1293.                                 SetPrefToDefaults(&PrivatePhonebook[i] -> Config,NULL);
  1294.  
  1295.                                 if(ReadChunkBytes(Handle,PrivatePhonebook[i] -> Name,LastSize) == LastSize)
  1296.                                 {
  1297.                                     if(PhonePasswordUsed)
  1298.                                         Decrypt((UBYTE *)PrivatePhonebook[i] -> Name,LastSize,PrivatePhonebook[i] -> Name,PhonePassword,20,NewStyle);
  1299.  
  1300.                                     Last = i;
  1301.  
  1302.                                     PrivatePhonebook[i] -> Count = -1;
  1303.  
  1304.                                     i++;
  1305.  
  1306.                                     LastHadTime = FALSE;
  1307.                                 }
  1308.                                 else
  1309.                                 {
  1310.                                     if(i)
  1311.                                         Size = i - 1;
  1312.                                     else
  1313.                                         Size = 0;
  1314.  
  1315.                                     break;
  1316.                                 }
  1317.                             }
  1318.                         }
  1319.  
  1320.                         if(Chunk -> cn_ID == 'TIME')
  1321.                         {
  1322.                             if(Last != -1)
  1323.                             {
  1324.                                 for(j = 0 ; j < Chunk -> cn_Size / sizeof(struct TimeDate) ; j++)
  1325.                                 {
  1326.                                     if(TimeDateNode = CreateTimeDateNode(-1,-1,""))
  1327.                                     {
  1328.                                         if(ReadChunkBytes(Handle,&TimeDateNode -> TimeDate,sizeof(struct TimeDate)) == sizeof(struct TimeDate))
  1329.                                         {
  1330.                                             if(PhonePasswordUsed)
  1331.                                                 Decrypt((UBYTE *)&TimeDateNode -> TimeDate,sizeof(struct TimeDate),(UBYTE *)&TimeDateNode -> TimeDate,PhonePassword,20,NewStyle);
  1332.  
  1333.                                             AdaptTimeDateNode(TimeDateNode);
  1334.  
  1335.                                             AddTail((struct List *)&PrivatePhonebook[Last] -> TimeDateList,&TimeDateNode -> VanillaNode);
  1336.  
  1337.                                             LastHadTime = TRUE;
  1338.                                         }
  1339.                                     }
  1340.                                 }
  1341.                             }
  1342.                         }
  1343.                     }
  1344.  
  1345.                     if(Size)
  1346.                     {
  1347.                         if(!LastHadTime && Last != -1)
  1348.                         {
  1349.                             if(TimeDateNode = CreateTimeDateNode(-1,-1,""))
  1350.                             {
  1351.                                 TimeDateNode -> TimeDate . PayPerUnit[0]    = PrivatePhonebook[Last] -> PayPerUnit[0];
  1352.                                 TimeDateNode -> TimeDate . PayPerUnit[1]    = PrivatePhonebook[Last] -> PayPerUnit[1];
  1353.  
  1354.                                 TimeDateNode -> TimeDate . SecPerUnit[0]    = PrivatePhonebook[Last] -> SecPerUnit[0];
  1355.                                 TimeDateNode -> TimeDate . SecPerUnit[1]    = PrivatePhonebook[Last] -> SecPerUnit[1];
  1356.  
  1357.                                 TimeDateNode -> TimeDate . TimeOfDay[0]    = PrivatePhonebook[Last] -> TimeOfDay[0];
  1358.                                 TimeDateNode -> TimeDate . TimeOfDay[1]    = PrivatePhonebook[Last] -> TimeOfDay[1];
  1359.  
  1360.                                 AddTail((struct List *)&PrivatePhonebook[Last] -> TimeDateList,&TimeDateNode -> VanillaNode);
  1361.                             }
  1362.                         }
  1363.  
  1364.                         if(Phonebook)
  1365.                             DeletePhonebook(Phonebook,PhoneSize,TRUE);
  1366.  
  1367.                         Phonebook = PrivatePhonebook;
  1368.                         PhoneSize = PrivatePhoneSize;
  1369.  
  1370.                         NumPhoneEntries = Size;
  1371.  
  1372.                         Success = TRUE;
  1373.                     }
  1374.                     else
  1375.                     {
  1376.                         if(PrivatePhoneSize)
  1377.                         {
  1378.                             DeletePhonebook(PrivatePhonebook,PrivatePhoneSize,TRUE);
  1379.  
  1380.                             Success = FALSE;
  1381.                         }
  1382.                     }
  1383.  
  1384.                     FreeDialList();
  1385.                 }
  1386.  
  1387.                 CloseIFF(Handle);
  1388.             }
  1389.  
  1390.             Close(Handle -> iff_Stream);
  1391.         }
  1392.  
  1393.         FreeIFF(Handle);
  1394.     }
  1395.  
  1396.     if(UseOld)
  1397.         Success = OldLoadPhonebook(Name);
  1398.  
  1399.     return(Success);
  1400. }
  1401.